Mac-Style Cover Flow Photo Gallery with CSS Scroll Snap
The Mac-style photo gallery, the one where covers fan out in 3D and the centre image faces you, no longer needs Photoshop mock-ups, a Flash component or an XML file. Today it is a scrolling list, CSS scroll snap and a scroll-driven animation: a few dozen lines of CSS and no required JavaScript.
This tutorial builds that gallery from scratch. You get a coverflow that works with touch, mouse wheel and keyboard, tilts each cover as it moves through the centre, and degrades to an ordinary swipeable row where the newest CSS is not available.

How the original worked, and why it had to go
The 2007 version drew the perspective look in Photoshop with Warp transforms, then relied on a third-party Flash component that loaded photos from an XML file. Adobe ended support for Flash Player at the end of 2020 and browsers removed it. The effect is still worth building as a compact way to browse albums, products or posters, and now the browser does the 3D work while the images stay real images that search engines and screen readers can read.
The building blocks
Four CSS features do the work. None of them need a library.
- Scroll snap turns a plain horizontally scrolling list into something that always settles on one item. It is widely available across browsers and is what gives the gallery its tactile, one-cover-at-a-time feel.
- 3D transforms with
perspectivetilt and push covers back in depth.perspectivegoes on the scroll container, and the items are positioned in 3D space inside it. - Scroll-driven animations link an animation to scroll position instead of time. With
animation-timeline: view()each cover animates according to where it sits in the scrollport: entering, centred, or leaving. This is the part that replaces the Flash component. It works in Chrome and Edge from version 115 and in Safari 26. Firefox enables it by default from version 159; at the time of writing that release is in beta and Firefox 158 and earlier ignore the property. Because it is not yet Baseline, the demo treats it as an enhancement. -webkit-box-reflectdraws the Apple-style reflection. It is non-standard but works in Chromium and Safari. Browsers that lack it simply show no reflection.
Step 1: Mark up the gallery as a list
A gallery is a list of images, so use one. Each item wraps a single img in a span that we will animate. The scroller needs tabindex="0" so keyboard users can focus it and scroll with the arrow keys, and a label so a screen reader announces what it is.
<div class="flow" tabindex="0" role="region" aria-label="Album covers">
<ul class="track">
<li class="cover"><span class="card"><img src="covers/01.jpg" alt="Blue fjord seen from a rocky cliff edge" width="520" height="520"></span></li>
<li class="cover"><span class="card"><img src="covers/02.jpg" alt="Green hills and a winding road under a cloudy sky" width="520" height="520"></span></li>
<!-- more covers -->
</ul>
</div>
Write real alt text for each photo. Because the images are normal elements, every one is available to assistive technology whether or not the 3D effect runs.
Step 2: Build the scroller and the track
The outer .flow element scrolls and owns the perspective. Inside it, .track is a flex row that preserves 3D, so covers sort by depth and a closer cover correctly overlaps a farther one.
:root {
--cover: min(52vw, 260px);
}
.flow {
width: 100%;
max-width: 1100px;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x mandatory;
perspective: 900px;
perspective-origin: 50% 40%;
scrollbar-width: none;
}
.flow::-webkit-scrollbar {
display: none;
}
.flow:focus-visible {
outline: 3px solid oklch(0.8 0.15 230);
outline-offset: -6px;
}
.track {
display: flex;
width: max-content;
margin: 0;
/* Let the first and last cover reach the centre. */
padding: 3rem calc(50% - var(--cover) * 0.35) 5rem;
list-style: none;
transform-style: preserve-3d;
}
Two details deserve explanation. The horizontal padding is half the scroller width minus half a cover (adjusted for the overlap below), which is what lets the first and last covers scroll all the way to the middle. And :focus-visible gives keyboard users a clear outline without showing it on every mouse click.
Step 3: Snap one cover at a time
Each li is a snap target aligned to the centre, and a negative inline margin pulls neighbours together so they overlap like a fanned stack.
.cover {
flex: 0 0 var(--cover);
width: var(--cover);
margin-inline: calc(var(--cover) * -0.15);
scroll-snap-align: center;
scroll-snap-stop: always;
cursor: pointer;
transform-style: preserve-3d;
}
/* A span is inline, and inline elements ignore transforms. */
.card {
display: block;
}
.cover img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 1;
object-fit: cover;
border-radius: 6px;
box-shadow: 0 20px 40px rgb(0 0 0 / 0.35);
-webkit-box-reflect: below 2px linear-gradient(transparent 65%, rgb(0 0 0 / 0.35));
}
scroll-snap-stop: always stops a hard flick from skipping several covers, which suits a gallery where each item is worth seeing. Notice that the snapping element, the li, is not the element we transform. That is deliberate. Browsers calculate snap positions from an element’s box, and if the same element also scales and rotates as it scrolls, the snap point drifts and the centred cover ends up off-centre. Keeping the transform on an inner .card keeps snapping stable. The height: auto on the image lets aspect-ratio win over the height attribute, which would otherwise stretch each photo. The display: block on .card matters too: it is a span, which is inline by default, and transforms do not apply to inline elements.
Step 4: Tilt covers with a scroll-driven animation
Now the coverflow effect. The animation runs on .card and uses view(inline) as its timeline. Progress is 0% when a cover enters the scrollport, 50% when it is centred, and 100% when it leaves. The keyframes map those positions to a tilt: angled one way on the right, flat and pushed forward in the middle, angled the other way on the left.
@supports (animation-timeline: view()) {
.card {
animation: flip linear both;
animation-timeline: view(inline);
}
}
@keyframes flip {
0%, 40% {
transform: translateX(calc(var(--cover) * 0.12)) translateZ(-150px) rotateY(58deg);
filter: brightness(0.55);
}
50% {
transform: translateZ(120px);
filter: brightness(1);
}
60%, 100% {
transform: translateX(calc(var(--cover) * -0.12)) translateZ(-150px) rotateY(-58deg);
filter: brightness(0.55);
}
}
The flat stretches at 0 to 40% and 60 to 100% are what make the tilt look like a fixed pose. Without them, covers far from the middle would keep rotating as you scroll. The side covers also darken a little, which pushes them back visually and keeps the centre cover the focus. Because the animation is tied to scroll position and not a clock, there is nothing to start, stop or sync: the scroll position is the single source of truth.
The @supports wrapper is the fallback. Where scroll-driven animations are missing, the cards never animate, and visitors get a flat, snapping row of covers that still scrolls and swipes properly.

Step 5: Let people click a cover to bring it forward
Scrolling covers a lot, but the original Apple interface also let you click a side cover to bring it to the middle. That needs a few lines of JavaScript, using scrollIntoView so the snap points do the rest.
const flow = document.querySelector('.flow');
const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)');
flow.addEventListener('click', (event) => {
const cover = event.target.closest('.cover');
if (!cover) return;
cover.scrollIntoView({
behavior: reduceMotion.matches ? 'auto' : 'smooth',
inline: 'center',
block: 'nearest',
});
});
With the track padding from Step 2, the first cover starts centred, so you do not need to set an initial position. To open on a different cover, call scrollIntoView on it once at load, for example document.querySelector('.cover:nth-child(5)').scrollIntoView({ inline: 'center', block: 'nearest' }). The gallery already works without this script, so treat it as a progressive enhancement. If a cover should open a larger view, hand it off to a lightbox; our modern lightbox tutorial covers that pattern.
Accessibility and motion
A 3D carousel is a lot of movement, so respect people who have asked their system for less of it. The scroll-driven tilt is driven by the user’s own scrolling, but a strong rotation can still be uncomfortable. Switch it off for people who set the reduced-motion preference. This media query is widely available.
@media (prefers-reduced-motion: reduce) {
.card {
animation: none;
}
}
With the tilt off, the gallery is still a clean snapping row. A few more rules keep it usable.
- Keep the scroller focusable and labelled so keyboard users can reach it, and keep the visible focus outline.
- Give every image meaningful alt text and explicit
widthandheightto avoid layout shift while photos load. - Do not put essential text only on the side covers. Anything dimmed and angled is harder to read, so reserve captions for the centre item or a caption area below the gallery.
- Consider adding previous and next buttons if the gallery is a primary way to navigate, because not everyone discovers horizontal scrolling.
Browser support at a glance
| Feature | Status | If unsupported |
|---|---|---|
| Scroll snap | Widely available | Not applicable, the row still scrolls |
3D transforms and perspective |
Widely available | Not applicable |
Scroll-driven animations (view()) |
Not yet Baseline: Chrome and Edge 115+, Safari 26+, Firefox 159+ (beta at time of writing) | Flat snapping row, no tilt |
-webkit-box-reflect |
Non-standard; Chromium and Safari | No reflection |
prefers-reduced-motion |
Widely available | Not applicable |
The reflection is the only non-standard piece, and the page loses nothing important without it. If you want a reflection everywhere, you can draw one yourself with a flipped, masked copy of the image, at the cost of duplicate markup or a CSS variable holding the image URL.
Make it your own
All the numbers sit in a handful of places, so tuning the feel is quick.
- Spacing: change the negative
margin-inlineon.cover. More overlap makes a tighter stack; less shows more of each side cover. If you change it, adjust the track padding by the same amount so the first cover still reaches the centre. - Angle and depth: edit
rotateYand thetranslateZvalues in the keyframes. Larger angles feel more dramatic but make side covers harder to read. - Perspective: a lower
perspectivevalue exaggerates depth. Around 800px to 1200px looks natural for covers this size. - Cover size: change
--cover. It usesmin()so covers shrink on small screens.
If a full 3D coverflow is more than your design needs, simpler options exist. Our coverflow image carousel snippet is a ready-made version, the scroll snap card slider shows the flat approach, and the photo gallery with modal lightbox is a better fit when people need to inspect each photo. To go deeper on the transforms used here, start with Easy CSS Animation With Transition and Transforms, and for polishing the images themselves, see CSS3 Image Styles.
Frequently asked questions
Do I still need Flash or a plugin for a cover flow gallery?
No. Flash is gone from browsers, and the effect is plain CSS now. Scroll snap handles the stepping, 3D transforms handle the look, and a scroll-driven animation connects the two.
Why animate an inner element instead of the list item?
Snap positions are calculated from an element’s box. If the snapping element also scales and rotates while scrolling, the snap position moves and the centred cover drifts off-centre. Transforming an inner wrapper keeps the snap target steady.
What happens in a browser without scroll-driven animations?
The @supports rule skips the animation and visitors get a flat, snapping row of covers. It is less dramatic, but every image is still reachable by swipe, scroll wheel and keyboard.
First of all, I’d like to congratulate you on the fabulous design job with webdesignerwall. I’m loving this photoflow component and love the stuff you’ve done with it. Since its’ xml, I’m sure we can link each image to a post or page on the site as well! Thanks for the tutorial and I might do one for my site for easy navigation of posts, once I can afford this component
Great job again.
I read somewhere that in Flash, to get rid of that aliasing when an image animates, you had to export in “High” quality and not “Maximum” quality. I once created a carrousel with external images through a XML file (just like you do) and exported in “Maximum” quality, and it looked very aliased.
In any case, it looks wonderful, I will surely use it.
I sent you an email to congratulate you on this great website, and I’ll say it again: I love this site. Keep it going on.
Jeremy Thomas
How did you create that thumbnail grid, I’m new to photoshop.
How can i use different xml files? If i want to load different gallerys with different xml, where can i specify the xml filename? Thanks.
Ok i have searched and I must just be stupid but…
How do you create a grid!
Nice indeed. But just so you know that credit should be given to this guy who created COVER FLOW back in the day. Apple bought it from him and have used it everywhere from iTunes to the iPhone :-)
Cheers
Great job, I need a better photo flash gallery then the ones I use for my friends. Currently I am using slide show pro which is great and so is simple viewer but this looks a lot better and easier to use.
Ho my god!….wonderful!….i love your art works….i’m a Fan of you!….even tought…the gallery miss of a link to navigate back and forward into the images…
But it’s wonderful!
Compliments!
@huey – Thanks for your information. I didn’t know that CoverFlow was originally created by steelskies.com
Great! :D
but anyone know how can I change the photo size?
;) thnks
I like the tutorial, my only problem with it, and the components listed in the comments is that they are not accurate, they simply skew/mask the images, rather than actually placing them in a perspective. Most people probably wouldn’t know the difference, but it is noticeable.
Though quietlyscheming’s DisplayShelf is good N99 is better because you can use your own images and just XML editing.Also the images move both ways with just the scroll wheel of the mouse itself.
Looking forward to going in detail with this beautifull piece of software.
I love it!!
But how do i add links to the pics? {without the flash component but via the XML file}
Cheers
@Chike – To add a link to the image via XML, please read the user guide at Flashloaded: (under Using XML)
hello,its a very gu work n website
herm…a reader from wedesigner mag you are hummm ? :)
Not only is this tutorial simply amazing, letting us in on the “secrets” of the pro’s – but giving it away to the masses makes us all better designers. Thank you.
A creative mind in progress with thirst. photoFlow is the way to go
could anyone tell me how to create the thumbnail grid in photoshop….
Could anyone please tell me how to make a thumbnail grid in Photoshop? I’ve searched Google with no help. I’d really appreciate the tip. Thanks.
harika yapmışsınız bayıldım süpersiniz :)
yeah… how do you make a thumbnail grid??? PLEASE tell us?
you forgot a step (right before step 4)…
in your picture the TOP of the image also has a gradient mask/gradient overlay…
because its faded out. maybe adding that step woulda helped us who follow strictly by what the tutorial says ;)
How can I use this tutorial. If I don’t have photoflow..
I want photoflow, it will be useful for my firefox gallery (I develop firefox themes :D)
Nice work on your website ^^
I believe you can make a thumbnail grid under the file–>automate–>contactsheet or something like that. I’m at work right now, so I can’t confirm. You still might have to do some editing afterwards. Just one easy way.
thanks for your great work, things like this make internet more friendly, i think so; for us… the begginers in web design.
Really really nice ive always wondered how to create something like that on photoshop
great stuff! how do you add a txt description to the image? something through the xml right? and adding dynamic txt box in flash right?
nice tutorial ,
just confuse how to upload this .swf on the internet..im upload but no picture appear..what should i do??…something missing on my component or my uploading step..
really need a help..
amazing tutorial and download. xml photo galleries are making this technology more accessible to the common artists that might have perhaps a little technological knowledge and a lot of artistic vision/ambition. thank you for taking the time to put this together.
Can you do update the code to allow autoscrolling of thumbnails when we point the mouse cursor to the left or to the right side? It would be perfect with this option added! Also maybe add comments in bottom… Like (picture details like description, exposure, aperture,…). TY for sharing with us :)
o0k well, how can i give a link on active photos? for example, there will be some photos at bottom side of page that active, and we click on them to change photos. on a photo, i wanna give a link by clicking to go a another else web site. i dunno how to do that :( please help me!
regards!
Since when do they charge for stuff on Kirupa.com (the photoflow component you have to download) – gah! Has anybody got a tutorial to write this not as a component?
for variety of flash compone visite our site
http://www.saffronflashcms.com
for variety of flash components visit our site
http://www.saffronflashcms.com
[email protected] –
Since it is an embedded flash application you will either have to create a movieclip in Flash (you can do this on the Flash timeline or by loading a movieclip externally onto the root) OR by using –
on(release) {
getURL(www.example.com, “_blank”);
}
on a button or movieclip in Flash.
podtim –
The swf will get the images externally just like a browser will, so any files that are referenced in the xml file must be in the same place relative to the swf file. In other words, if your images are referenced as being in the ‘images’ folder, when you upload your swf you must also upload you images in a folder called ‘images’ in the same directory as the swf file. Also, your xml file must be present in order for the swf to get the image files. Upload everything and see if it works.
I love this! I’ve been looking for a tut on this type of navigation since I saw it on the new iphone. I’m not pro, but I will be someday. I’m trying to teach myself everything I can and get all the programs possible to do that. Is there a way to perhaps rerun the contest? With two kids to homeschool, I’m broke lol. I’d love, and use, the photoflow!
I agree with the person who was confused about how to create a thumbnail grid. Everything seems straightforward, but there seemed to be some giant leaps over how to do that. My Google search for creating one didn’t bring up any signigicant results either. Please help. Thanks, Monica
I would like how to make a thumbnail grid. Does anyone have any idea?
I think to create a thumbnail grid the easiest way is get some images and make a square out of them (3 across, 3 down) put them into a layer set, then duplicate that layer set and move it around your page until the layer sets take up the size of your background.
Excellent tutorial, many thanks
Thanks a ton for this tutorial. I don’t know if I would ever use it, as I’m not too into Flash stuff, but it looks pretty rad. Keep posting unique tutorials like this one.
ok, so I’m downloading ps cs3 now to do the wrap effect because its not on ps 7 lol… but i just bought the photo flow for flash 8.. and its being shipped does anyone know how long it takes to ship this thing?
could you please define what is the size of the thumbnail grid photo and if possible how to quickly make one in Photoshop maybe?
Hi Guys, I am very late to enter the contest of getting photoflow component but would any of you guys be soo kind to give me a copy of this component please? :) I know its cheeky to as but by looking at the example, this looks soo professional and would like to do my own photo gallery websites. Any help appreciated, many thanks, Sahid.
It looks great! I would love to include PhotoFlip onto my WordPress Site. How to I incorporate it onto wordpress? What I would liek to do, is to 1st get the demo version working on my wordpress site to make sure I know how to, before I design my own PhotoFlip with the guide given above.
Any ideas, I am not totally knew to wordpress, but don’t understand that much about coding.
How can i insert an external link (a href=”http://www.google.com/”) to each picture ?
awesome .. nice tips…. i find only one issue that it takes static images. It would be great if it take images from rss feeds (e.g. from flickr).
Flash experts from india!
Flash Specialist for building full flash websites.
i wanna use photoflow.Its a really good effect.
Hi Love your flash but have a question (not so good in flash myself you c): Was wondering if it is posible to make a horizontal scroller so that you don’t need to click on every picture to get the next one? If there is would you tell me how to please?
Kind Regards
Hi Love your flash but have a question (not so good in flash myself you c): Was wondering if it is posible to make a horizontal scroller so that you don’t need to click on every picture to get the next one?
never mind, fixed it. Img size was the problem. If an image is smaller then the size you want it wont appear
is there any short cut to the new version of flash for photoFlow.
never mind, fixed it. Img size was the problem. If an image is smaller then the size you want it wont appear
Me pueden ayudar a saber como hacer esta Galeria en la web Desafio Esteli?
What an awesome Tool! Im playing around with it as we speak. One question though. How do I change the background? Currently it set on a mosaic design, I want it to be all black. How do I go about doing this? Thanks a lot!
Francis
Hey!! Man, WOW!! that’s a great tut there. You are a GOD of designing. I tried this ,got the component dragged it , modified the properties as you’ve showed here in the tut, but…… after publishing the images are not displyed. I can only see white , blank squares, I can flip them, though.
What the prob could be? I’m using Flash 8 version. Please reply on my e-mail id [email protected] .I need it very badly!!.
Thanks.
All I can say is overexposure to pure Awesomeness….!!! great tutorial…keep up the good work.
it looks great…
does photoflow work with flash cs4?
Very pretty but is it possible to put a link on each photo?
i search to modify the xml but i didn’t found anything
thanks
Download Zip package……… there is some problem in zip file
if anyone needs the photoFlow…i have it so just send me an email and i will send it to you.
Wicked version on photoflow mate, well done. Is there any chance of grabbing the the .fla file off you to learn how its done… Understandable if you cant.
Thanks
Les
Can someone help me with this gallery, i designed my site in flash, now i want to finish it by adding the gallery, it’s a portfolio site, but I don’t know how to use this. COULD SOMEONE PLEASE HELP :(
[email protected]
Amy, can you,please, send me the Photo Flow component?! Thanks. Yana
[email protected]
Hi,
Can you send me the Photoflow please? Thanks. My email address is [email protected]
How to take away the wall behind it? I just want black or white wall behind it? Can you do it in Flash 9?
How to link the images to weblinks?
Please help, Thanks.
Kpss cd aöf dvd laptop etiket klavye sticker
kpss dvd aöf cd dgs vcd laptop etiket sticker etiket yabancı dil cd
hey can someone send me the fla file of this??? i need to do some changes my email is [email protected]
thx bro, i searched i will use that backgorund with Xirod font!!
tnx
thx bro, i searched i will use that backgorund with Xirod font!!
tnxx
Hi,
This is wonderful stuff. Love to use it for a website. Many I know is’t okay to use it? Please let me know.
The designs showed here show what simple and tasteful design is all about. Another one to consider
How did you create that thumbnail grid, I’m new to photoshop.
How did you create that thumbnail grid, I’m new to photoshop
are you paid by Flashloaded?
doing such a tutorial is a joke. this is just comercial advertising for flashloaded. if you would show how to build this in as2 or 3 then i would say wow…. but this tastet just bad…
this is the best flash images gallery
thanx to free download
Hii , thanks for this great gallery
Is there a way to change the background image in the free demo you gave here for download?
Thanks
Hi.
Das Teil ist ja absolut genial.
Kann ich die FLA dazu bekommen?
Liebe Grüße
RM
I learnt my picture editing using fireworks 8 but i can navigate my way decently around photoshop. however, i dunno how to create the thumbnail grid in photoshop. could you please include a tutorial for that as well? thank you
I really like the post. I’m looking foward to reading more. TY!
It relies heavily on touch because the pages I have a user acting on, are usually a collection of child records. uggs outlet Caching is a big help in this respect.Thanks
If I got a chance, i will prefer buying the iphone 4 white but not the iphone 4 Black. Who can tell me where is the white iphone 4 available? I would really want to take one.
It’s sorry to hear that Some white iPhone 4 buyers have reported signal reduction when the phone is held in certain ways, especially in the left hand, as the antenna problem is in the bottom left corner of the phone’s side casing. Is that mean i have to wait longer to get the white iphone 4?
Güzel bir çalışma.teşekkürler
hi…
i see about this flash and it is really good.
actually i need the FLA of this can u send it in my email [email protected]
coz i want to insert it in my website
Always a pleasure reading your sophisticated-ly engineered articles.
can any body send me the source file
Make a bored visitor into a customer. Custom website we design will convey a strong image for your customers.
Web Application Design
Another questionnaire, the participants’ problem identification and structuring, idea generation, problem elaboration and clarification, such as creativity, problem solving insertion sezkin idea which one’s preferred styles are evaluated. While participants preferred the style of non-disclosure and intellectual development of ADHD, with ADHD, participants chose to produce ideas.
OH,it’s so helpful to me,and your blog is very good,I just couldnt leave your web site prior to saying that I definitely loved the quality facts you.You all do this kind of a great job at these Concepts… cannot tell you how significantly I, for one particular appreciate all you do!
Magnificent goods from you, man. I have understand your stuff previous to and you are just extremely fantastic. I really like what you’ve acquired here, certainly like what you’re stating and the way in which you say it. You make it enjoyable and you still take care of to keep it sensible. I cant wait to read much more from you. This is actually a wonderful website. Kind regards, Rudy James
Hi,
I understands the tutorial but upto photoshop part. I have added component as well in flash but now how to write xml for this? please help me.
With havin so much written content do you ever run into any problems of plagorism or copyright violation? My site has a lot of exclusive content I’ve either created myself or outsourced but it appears a lot of it is popping it up all over the internet without my permission. Do you know any solutions to help prevent content from being stolen? I’d genuinely appreciate it.
Hi, very nice design and still up to date !!
I would like to use your gallery for my private website. can u send me the fash files (fla) pls, if u still have it.
to [email protected]
have a nice day :)
you may have an incredible blog here! would you prefer to make some invite posts on my weblog?
hello, thanks alot for this tutorial !! Please i would like to know how did you create the thumbnail grid using multiple photos. did you use photoshop? I need to do the same type of grid. Id appreciate any advise. Thanks alot
[email protected]
Hey not to set off topic but can anyone give me overview of. New York Car Insurance Reform 295 Greenwich St, New York, NY 10007 (646) 351-0824 They are down the block with me. I was wondering if they were a good insurance company. I need to acquire coverage, it is the law you know, but I have to have a good price price plus I want friendly service.
Wow – this is a great step-by-step. You really know how to use the products for great effect *sigh*. I love how you warp the image then apply the spotlight effect. I would never have come up with something like that. Any chance of getting hold of a few stem cells to give myself a cerebal upgrade? I’m only a man anyway so I have a decent excuse :) Well done and great work.
My site has a lot of exclusive content I’ve either created myself or outsourced but it appears a lot of it is popping it up all over the internet without my permission. Do you know any solutions to help prevent content from being stolen?